package br.com.it4.zmed.persistence;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import br.com.it4.framework.persistence.dao.BaseDAOImpl;
import br.com.it4.framework.persistence.exception.PersistenceException;
import br.com.it4.zmed.entity.Exame;
import br.com.it4.zmed.filter.ExameFilter;

/**
 * Repositório para persistência básica para o exame.
 * 
 * @author Mozart Silva (mozart.vsilva@gmail.com)
 * 
 */
@Repository(value = "exameRepository")
public class ExameDAOImpl extends BaseDAOImpl<Exame> implements ExameDAO {

    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    public List<Exame> get() throws PersistenceException {
        List<Exame> exames = null;
        try {
            EntityManager entityManager = this.getEntityManager();

            StringBuffer jpql = new StringBuffer();
            jpql.append("select exame from Exame exame ");
            jpql.append("order by exame.nome ");

            Query query = entityManager.createQuery(jpql.toString());
            exames = query.getResultList();
        } catch (Exception e) {
            throw new PersistenceException(e);
        }
        return exames;
    }

    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    public List<Exame> get(ExameFilter filtro, int registroInicio, int registroFim) throws PersistenceException {
        List<Exame> exames = null;
        try {
            Query query = this.getQuery(filtro, false);
            query.setFirstResult(registroInicio);
            query.setMaxResults(registroFim);
            exames = (List<Exame>) query.getResultList();
        } catch (Exception e) {
            throw new PersistenceException(e);
        }
        return exames;
    }

    /** {@inheritDoc} */
    public Long getCount(ExameFilter filtro) throws PersistenceException {
        Long count = null;

        try {
            Query query = this.getQuery(filtro, true);
            count = (Long) query.getSingleResult();
        } catch (Exception e) {
            throw new PersistenceException(e);
        }

        return count;
    }

    /**
     * Monta query de consulta de exame.
     * 
     * @param filtro
     *            Filtro para montagem da query.
     * @param isCount
     *            true se é um count da consulta e false caso seja um consulta
     *            dos dados.
     * @return A Query montada.
     */
    private Query getQuery(ExameFilter filtro, boolean isCount) {
        EntityManager entityManager = this.getEntityManager();

        StringBuffer jpql = new StringBuffer();
        if (!isCount) {
            jpql.append("select exame from Exame exame ");
        } else {
            jpql.append("select count(exame) from Exame exame ");
        }

        jpql.append("where 1 = 1 ");

        if (filtro.getNome() != null && !filtro.getNome().isEmpty()) {
            jpql.append("and upper(exame.nome) like upper(:nomeExame) ");
        }

        if (!isCount) {
            jpql.append("order by exame.nome ");
        }

        Query query = entityManager.createQuery(jpql.toString());

        if (filtro.getNome() != null && !filtro.getNome().isEmpty()) {
            query.setParameter("nomeExame", "%" + filtro.getNome() + "%");
        }

        return query;
    }
}